package io.github.burukeyou.dataframe.iframe.group;

import java.util.Comparator;
import java9.util.function.Function;

import io.github.burukeyou.dataframe.iframe.window.Sorter;

/**
 * @author caizhihao
 * @param <T>
 */
public class GroupWindowImpl<T> implements GroupWindow<T> {

    protected Comparator<T> distincter;

    protected Sorter<T> sorter;

    public GroupWindowImpl(Comparator<T> distincter) {
        this.distincter = distincter;
    }

    public GroupWindowImpl(Sorter<T> sorter) {
        this.sorter = sorter;
    }

    @Override
    public <U extends Comparable<? super U>> GroupWindow<T> sortAsc(Function<T, U> sortField) {
        if (sorter == null) {
            this.sorter = Sorter.sortAscBy(sortField);
        } else {
            sorter.sortAsc(sortField);
        }
        return this;
    }

    @Override
    public <U extends Comparable<? super U>> GroupWindow<T> sortDesc(Function<T, U> sortField) {
        if (sorter == null) {
            this.sorter = Sorter.sortDescBy(sortField);
        } else {
            sorter.sortDesc(sortField);
        }
        return this;
    }


    @Override
    public <U extends Comparable<? super U>> GroupWindow<T> distinct(Function<T, U> distinctField) {
        // 创建新的比较器
        Comparator<T> newComparator = new Comparator<T>() {
            @Override
            public int compare(T o1, T o2) {
                U key1 = distinctField.apply(o1);
                U key2 = distinctField.apply(o2);
                // 空值处理：null 视为最小值
                if (key1 == null) return key2 == null ? 0 : -1;
                if (key2 == null) return 1;
                return key1.compareTo(key2);
            }
        };

        // 组合比较器逻辑
        if (distincter == null) {
            distincter = newComparator;
        } else {
            final Comparator<T> existing = distincter; // 保存现有比较器
            distincter = new Comparator<T>() {
                @Override
                public int compare(T o1, T o2) {
                    int result = existing.compare(o1, o2);
                    if (result == 0) {
                        return newComparator.compare(o1, o2);
                    }
                    return result;
                }
            };
        }
        return this;
    }

    @Override
    public GroupWindow<T> distinct(Comparator<T> distinctComparator) {
        if (distincter == null) {
            distincter = distinctComparator;
        } else {
            distincter = distincter.thenComparing(distinctComparator);
        }
        return this;
    }

    public Comparator<T> getDistincter() {
        return distincter;
    }

    public Sorter<T> getSorter() {
        return sorter;
    }

    public void setDistincter(Comparator<T> distincter) {
        this.distincter = distincter;
    }

    public void setSorter(Sorter<T> sorter) {
        this.sorter = sorter;
    }
}
